from django.shortcuts import render

# Create your views here.
"""
需求:     获取一个图片验证码


前端:     当用户第一次访问页面或者点击注册验证码的时候, 会发送一个请求.这个请求要携带 用户的唯一id [UUID]
            这个UUID是前端生成传递. 会随着请求传递给后端服务器

后端:
        请求
                GET         http://ip:port/image_codes/uuid/
        业务逻辑
                1. 接收请求参数
                2. 验证请求参数
                3. 生成图片验证码,获取图片验证码的内容[4个字母]
                4. 将 图片验证码的内容[4个字母] 保存到redis中. key:value
                        key --> uuid
                        value --> [4个字母]
                5. 返回响应
        响应
                返回图片二进制数据

"""
from django.views import View
from libs.captcha.captcha import captcha
from django_redis import get_redis_connection
from django.http import HttpResponse
class ImageCodeView(View):

    def get(self,request,uuid):
        # 1. 接收请求参数
        # 2. 验证请求参数 [作业的形式 课下自己实现自定义转换器]
        # 3. 生成图片验证码,获取图片验证码的内容[4个字母]
        # captcha.generate_captcha()  返回一个元组
        # 元组的第一参数 就是 图片验证码的内容[4个字母]
        # 元组的第二个参数 是图片二进制内容
        text,image_data =captcha.generate_captcha()
        # 4. 将 图片验证码的内容[4个字母] 保存到redis中. key:value
        #         key --> uuid
        #         value --> [4个字母]

        # 4.1 连接redis-server 创建redis-cli
        redis_cli = get_redis_connection('code')
        # 4.2 操作 string
        # setex(name, time, value)
        # 同 redis中 setex 指令
        # 120秒
        redis_cli.setex(uuid,120,text)
        # 5. 返回响应
        # 不设置 content_type 可以不可以!!!
        # return HttpResponse(image_data)

        return HttpResponse(image_data,content_type='image/jpeg')

"""

需求:
        发送短信验证码

前端:     
        当用户输入完图片验证码之后,点击发送短信验证码. 这个时候 前端要获取 手机号信息,用户输入的图片验证码内容和UUID
        就发送axios请求

后端:


    请求:
            GET   sms_codes/<mobile>/<uuid>/<text>/
                  sms_codes/?mobil=x&uuid=x     request.GET
                  
                  sms_codes/mobile/?uuid=xx&text=xx
    业务逻辑
            1. 接收参数
            2. 提取参数
            3. 验证参数
            
            4. 比对用户输入的图片验证码和服务器的图片验证码是否一致
            4.1 用户输入的图片验证码
            4.2 服务器的图片验证码.获取之后删除
            4.3 比对
            
            5. 生成短信验证码
            6. 保存短信验证码
            
            7. 发送短信验证码
            
            8. 返回响应
            
    响应:
            JSON {code:0}   
            


"""

from django.http import JsonResponse

class SMSCodeView(View):

    def get(self,request,mobile):
        # GET sms_codes/<mobile>/?image_code[用户输入的图片验证码]=xxxx&image_code_id[UUID 唯一标示]=xxxx
        # 1. 接收参数
        query_params = request.GET
        # 2. 提取参数
        image_code = query_params.get('image_code')
        image_code_id = query_params.get('image_code_id')
        # 3. 验证参数 [课上省略]
        # 3.1 验证 image_code的长度
        # 3.2 验证 imaage_code_id的 正则形式

        # 4. 比对用户输入的图片验证码和服务器的图片验证码是否一致
        # 4.1 用户输入的图片验证码

        redic_cli = get_redis_connection('code')
        redis_text = redic_cli.get(image_code_id)

        # 因为我们的图片验证码有一定的时效 获取的也可能是None
        if redis_text is None:
            return JsonResponse({'code':400,'errmsg':'图片验证码过期'})

        # 4.2 服务器的图片验证码.获取之后删除
        redic_cli.delete(image_code_id)

        # 4.3 比对
        if redis_text.decode().lower() != image_code.lower():
            return JsonResponse({'code': 400, 'errmsg': '图片验证码错误'})

        # 再发送前 判断 标记位是否有值 有值 说明是频繁操作
        flag = redic_cli.get('send_%s'%mobile)

        if flag:
            return JsonResponse({'code': 400, 'errmsg': '不要频繁操作'})

        # 5. 生成短信验证码
        from random import randint
        # 不满足 6位 补0
        sms_code = '%06d'%randint(0,999999)

        # ① 创建一个管道
        pipeline = redic_cli.pipeline()

        # ② 让管道收集指令
        # 6. 保存短信验证码
        pipeline.setex(mobile,300,sms_code)

        # 设置一个标记位.这个标记位的有效期是 60秒 标记位的值 是 任意值都可以
        pipeline.setex('send_%s'%mobile,60,1)


        # ③  执行管道
        pipeline.execute()

        # 7. 发送短信验证码
        # from utils.sms import send_sms_code
        # send_sms_code(mobile,sms_code,5)

        from celery_meiduo.sms.tasks import celery_send_sms_code
        #一定要注意: 必须通过 delay来调用!!!
        # 任务的参数 在delay中写入
        celery_send_sms_code.delay(mobile,sms_code,5)

        # 8. 返回响应
        return JsonResponse({'code':0})
